<template>
  <div class="Chart">
    <div class="panel-group">
      <div class="title">图表数据</div>
      <div class="page">
        <el-button type="primary" @click="back()" style="margin-right: 20px">
          <i class="el-icon-back"></i>
          返回
        </el-button>
        <el-button icon="el-icon-arrow-left" @click="changePage(-1)">
          上一页
        </el-button>
        <el-button @click="changePage(1)" style="margin-left: 20px">
          下一页
          <i class="el-icon-arrow-right el-icon--right"></i>
        </el-button>
        <span style="margin-left: 18%; font-size: 14px; color: #606266">
          导出组数 :
        </span>
        <el-input-number v-model="groupNumber" :min="15" :max="30" :step="5" step-strictly label="描述文字" size="small"
          style="margin-left: 10px"></el-input-number>
        <el-button type="primary" @click="sheet()" style="margin-left: 4%">
          导出Excel
        </el-button>
      </div>
      <div class="table-top">
        <div class="head" style="font-size: 22px; font-weight: 600; height: 38px">
          {{ title }}
        </div>
        <div class="head">
          日期：{{ chartsData.date1 }} 至 {{ chartsData.date2 }}
        </div>
        <div class="type">工序类型：{{ chartsData.processType }}</div>
        <div class="type">产品类型：{{ chartsData.productType }}</div>
        <div class="type">产品：{{ chartsData.product }}</div>
        <!-- 中间数据 -->
        <div style="border-top: 1px solid #bbb">
          測量單位 : {{ chartsValue.measuUnit }}
        </div>
        <div style="border-top: 1px solid #bbb">
          規格類型 : {{ chartsValue.specifications }}
        </div>
        <div style="border-top: 1px solid #bbb">
          規格上限 : {{ number(chartsValue.iUSL, "USL") }}
        </div>
        <div style="border-top: 1px solid #bbb">
          規格標準 : {{ number(chartsValue.iSL, "SL") }}
        </div>
        <div style="border-top: 1px solid #bbb">
          規格下限 : {{ number(chartsValue.iLSL, "LSL") }}
        </div>

        <!-- 根据规格类型，改变页面某些数据显示位置 -->
        <!-- <div>XUCL : {{ number(chartsValue.iUCLx, "UCLx") }}</div> -->
        <div>
          {{
            chartsValue.specifications == "双边对称"
              ? `XUCL : ${number(chartsValue.iUCLx, "UCLx")}`
              : chartsValue.specifications == "单边上限"
              ? `XUCL : ${number(chartsValue.iUCLx, "UCLx")}`
              : `XLCL : ${number(chartsValue.iLCLx, "LCLx")}`
          }}
        </div>
        <!-- <div>RUCL : {{ number(chartsValue.iUCLr, "UCLr") }}</div> -->
        <div>
          {{
            chartsValue.specifications == "双边对称"
              ? `RUCL : ${number(chartsValue.iUCLr, "UCLr")}`
              : `抽样方式 : 随机`
          }}
        </div>
        <div>Ca : {{ number(chartsValue.iCa) }}</div>
        <div>
          樣本/頻率:
          {{ chartsValue.sampleTimes + "次/" + chartsValue.sampleUnit }}
        </div>
        <div>控制類型: 解析用</div>

        <!-- <div>XCL : {{ number(chartsValue.iCLx, "CLx") }}</div> -->
        <div>
          {{
            chartsValue.specifications == "双边对称"
              ? `XCL : ${number(chartsValue.iCLx, "CLx")}`
              : `Max : ${number(chartsValue.maxValue)}`
          }}
        </div>
        <!-- <div>RCL : {{ number(chartsValue.iCLr, "CLr") }}</div> -->
        <div>
          {{
            chartsValue.specifications == "双边对称"
              ? `RCL : ${number(chartsValue.iCLr, "CLr")}`
              : `Min : ${number(chartsValue.minValue)}`
          }}
        </div>
        <div>Cp : {{ number(chartsValue.iCp) }}</div>
        <div>Std.Dev : {{ number(chartsValue.iSigmaP) }}</div>
        <div>Pp : {{ number(chartsValue.iPp) }}</div>

        <!-- <div>XLCL : {{ number(chartsValue.iLCLx, "LCLx") }}</div> -->
        <div>
          {{
            chartsValue.specifications == "双边对称"
              ? `XLCL : ${number(chartsValue.iLCLx, "LCLx")}`
              : `Cpk水準 : 1.670`
          }}
        </div>
        <!-- <div>RLCL : {{ number(chartsValue.iLCLr, "LCLr") }}</div> -->
        <div>
          {{
            chartsValue.specifications == "双边对称"
              ? `RLCL : ${number(chartsValue.iLCLr, "LCLr")}`
              : `PPM : ${number(chartsValue.iPPM)}`
          }}
        </div>
        <div>Cpk : {{ number(chartsValue.iCpk) }}</div>
        <div>Sigma : {{ number(chartsValue.iSigmaA) }}</div>
        <div>Ppk : {{ number(chartsValue.iPpk) }}</div>

        <template v-if="chartsValue.specifications == '双边对称'">
          <div>Max : {{ number(chartsValue.maxValue) }}</div>
          <div>Min : {{ number(chartsValue.minValue) }}</div>
          <div>Cpk水準 : 1.670</div>
          <div>PPM : {{ number(chartsValue.iPPM) }}</div>
          <div>抽样方式 : 随机</div>
        </template>
      </div>
      <div class="table" v-if="chartsValue">
        <div class="column" :style="`width:${100 / (15 * 1 + 1)}%`">
          <div class="row" style="background-color: #eee">组数</div>
          <div class="row" style="background-color: #eee">
            {{ tab_title[0] }}
          </div>
          <div class="row" style="background-color: #eee" v-show="chartsValue.specifications == '双边对称'">
            {{ tab_title[1] }}
          </div>
          <template v-if="chartsData.chartType !== '单值-移动极差图'">
            <div class="row" v-for="(item1, index1) in chartsValue.m_arrGrpSample[0]" :key="'a' + index1"
              style="background-color: #eee">
              {{
                chartsData.chartType == "单值-移动极差图"
                  ? "样本"
                  : "样本" + (index1 + 1)
              }}
            </div>
          </template>
        </div>
        <div class="column" :style="`width:${100 / (15 * 1 + 1)}%`" v-for="(item2, index2) in tableIndex"
          :key="'a' + index2">
          <div class="row" style="background-color: #eee">
            {{ chartsValue.m_arrXChart[item2] == undefined ? "" : item2 + 1 }}
          </div>
          <div class="row" @click="change(0, item2)" :style="
              chartsValue.m_arrXChart[item2] !== undefined &&
              storage.get('change')
                ? item2 == activationId
                  ? 'cursor: pointer; background-color: #00ff00;;'
                  : 'cursor: pointer'
                : ''
            " :title="
              chartsValue.m_arrXChart[item2] !== undefined &&
              storage.get('change')
                ? '点击进行修改'
                : ''
            ">
            {{
              chartsValue.m_arrXChart[item2]
                ? tab_title[0] == "均值"
                  ? chartsValue.m_arrXChart[item2].toFixed(3)
                  : chartsValue.m_arrXChart[item2].toFixed(decimal)
                : ""
            }}
          </div>
          <div class="row" @click="change(1, item2)" :style="
              chartsValue.m_arrRChart[item2] !== undefined &&
              storage.get('change')
                ? item2 == activationId
                  ? 'cursor: pointer; background-color: #00ff00;;'
                  : 'cursor: pointer'
                : ''
            " :title="
              chartsValue.m_arrRChart[item2] !== undefined &&
              storage.get('change')
                ? '点击进行修改'
                : ''
            " v-show="chartsValue.specifications == '双边对称'">
            {{
              (chartsData.chartType == "单值-移动极差图" && item2 == 0) ||
              chartsValue.m_arrRChart[item2] == undefined
                ? ""
                : chartsValue.m_arrRChart[item2].toFixed(decimal)
            }}
          </div>
          <template v-if="chartsData.chartType !== '单值-移动极差图'">
            <div class="row" v-for="(item3, index3) in chartsValue.m_arrGrpSample[0]" :key="'b' + index3"
              @click="change(2, item2, index3)" :style="
                chartsValue.m_arrXChart[item2] !== undefined &&
                storage.get('change')
                  ? item2 == activationId
                    ? 'cursor: pointer; background-color: #00ff00;;'
                    : 'cursor: pointer'
                  : ''
              " :title="
                chartsValue.m_arrXChart[item2] !== undefined &&
                storage.get('change')
                  ? '点击进行修改'
                  : ''
              ">
              {{
                chartsValue.m_arrGrpSample[item2] == undefined
                  ? ""
                  : chartsValue.m_arrGrpSample[item2][index3].toFixed(decimal)
              }}
            </div>
          </template>
        </div>
      </div>
    </div>
    <div class="panel-group">
      <div class="title">分析图形</div>
      <div class="chart">
        <div id="main1" :style="{ width: '950px', height: '400px', margin: '40px 0 0 0' }"></div>
        <div id="main2" :style="{ width: '950px', height: '400px', margin: '40px 0 0 0' }"
          v-show="chartsValue.specifications == '双边对称'"></div>
      </div>
    </div>
    <el-dialog v-loading="loading" :visible.sync="dialogVisible" title="修改" width="30%" :center="true"
      :lock-scroll="false">
      <div v-if="input_title === '标准差'">
        <span class="dialog" v-for="(item4, index4) in chartsValue.m_arrGrpSample[index]">
          <span>{{ "樣本" + (index4 + 1) }}：</span>
          <el-input v-if="sample[index4]" v-model="sample[index4]['value']" :placeholder="item4.toFixed(3)"
            style="width: 250px" @keyup.enter.native="update()" :disabled="sample[index4]['value'] == '0.00'">
          </el-input>
        </span>
      </div>
      <div v-else>
        <span class="dialog">
          <span>{{ input_title }}：</span>
          <el-input v-model="input" :placeholder="placeholder" style="width: 250px" @keyup.enter.native="update()">
          </el-input>
        </span>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="update()"> 确 定 </el-button>
      </span>
    </el-dialog>
    <div class="temporary">
      <div :id="'temporary_img1'" :style="{ width: groupNumber * 60 + 'px', height: '400px' }"></div>
      <div :id="'temporary_img2'" :style="{ width: groupNumber * 60 + 'px', height: '400px' }"></div>
    </div>
  </div>
</template>

<script>
import Vue from "vue"
import { changeChartValue } from "service/common"
import { midData } from './midData.js'
import saveAs from 'file-saver'

let Excel

if (localStorage.getItem('IE') !== "true") {
  Excel = require('exceljs');
}

export default {
  data() {
    return {
      loading: false,
      tableIndex: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], // 表格数据索引
      // chartsData: this.$store.state.chartsData, // 搜索条件k
      // chartsValue: this.$store.state.chartsValue, // 图表数据k
      chartsData: this.storage.get('chartsData'), // 搜索条件
      chartsValue: this.storage.get('chartsValue'), // 图表数据
      sampleValue: this.storage.get('sampleValue'), // 原始样本数据
      xData: [], // 图表x轴数据
      title: null, // 標題
      tab_title: [], // 表格第2、3行标题
      dialogVisible: false, // 弹出框
      input: '', // 修改文本框的值
      input_title: '', // 修改文本框的标题
      placeholder: '', // 文本框提示值
      index: 0, // 选择的数据索引
      index2: 0, // 选择的数据索引2（样本值）
      sample: [], // 样本文本框的值
      activationId: null, // 选中列id
      groupNumber: 15, // 导出组数
      decimal: 2, // 小数位数
    }
  },
  created() {
    if (this.chartsData === null) {
      this.$router.push('./select')
    }

    this.title = this.chartsData.chartType

    switch (this.chartsData.chartType) {
      case '单值-移动极差图': {
        this.tab_title = ['单值', '移动值']
        break;
      }
      case '均值-标准差图': {
        this.tab_title = ['均值', '标准差']
        break;
      }
      case '均值-极差图': {
        this.tab_title = ['均值', '极差']
        break;
      }
      case '中位数-极差图': {
        this.tab_title = ['中位数', '极差']
        break;
      }
    }
    this.calculate()
    midData(this.chartsData, this.chartsValue)
    this.MaxMin()
    this.specifications()

    if (this.chartsValue.specifications == '单边上限') {
      this.title = '上限趋势图'
    } else if (this.chartsValue.specifications == '单边下限') {
      this.title = '下限趋势图'
    } else {
      // this.title = '趋势图'
    }

    // 判断小数位数
    // 3位小数的产品列表
    let threeDecimalList = ['成檢_A268-2(CBK-006) OSP膜厚', '成檢_A270-3(CBK-005) OSP膜厚', '成檢_A291成品平坦度', '成檢_A306成品板厚', '成檢_A311-2 (CBK-011)OSP膜厚', '2ICU線孔銅厚度', '2ICU線零件孔孔銅厚度', '2ICU線導通孔孔銅']

    for (let i of threeDecimalList) {
      if (this.chartsData.productType.indexOf(i) !== -1) {
        this.decimal = 3
        break
      }
    }

    console.log(this.chartsValue)
  },
  mounted() {
    for (let i in this.chartsValue.m_arrChartDate) {
      let t1 = this.moment(this.chartsValue.m_arrChartDate[i]).format('HH:mm')
      let t2 = this.moment(this.chartsValue.m_arrChartDate[i]).format('MM/DD')
      this.xData.push(t1 + '\n' + t2)
    }
    for (let i in this.chartsValue) {
      if (this.chartsValue[i] == null) {
        this.chartsValue[i] = 0
      }
    }
    this.$nextTick(() => {
      this.chart('main1')
      this.chart('main2')
      this.chart('temporary_img1')
      this.chart('temporary_img2')
      // 两个图表联动
      let myChart1 = this.echarts.init(document.getElementById('main1'))
      let myChart2 = this.echarts.init(document.getElementById('main2'))
      this.echarts.connect([myChart1, myChart2]);
    });
  },
  methods: {
    // 处理数据，保留小数位
    number(value, index) {
      // 为上限时，需要为空的索引
      let ceiling = ['SL', 'LSL', 'CLx', 'LCLx', 'UCLr', 'CLr', 'LCLr']
      // 为下限时，需要为空的索引
      let lowerLimit = ['USL', 'SL', 'UCLx', 'CLx', 'UCLr', 'CLr', 'LCLr']
      if (value === 'NaN') {
        return 'NaN'
      } else {
        if (value === '----') {
          return '----'
        }
        if (this.chartsValue.specifications == '单边上限') {
          if (ceiling.indexOf(index) !== -1) {
            return '----'
          }
        } else if (this.chartsValue.specifications == '单边下限') {
          if (lowerLimit.indexOf(index) !== -1) {
            return '----'
          }
        }
        return value.toFixed(3)
      }
    },
    // 返回
    back() {
      this.$router.push('/select')
    },
    // 数据换页
    changePage(value) {
      let chartsValue = this.chartsValue
      if (this.tableIndex[0] + value * 15 < 0 || this.tableIndex[0] + value * 15 >= chartsValue.m_arrXChart.length) {
      } else {
        for (let i in this.tableIndex) {
          Vue.set(this.tableIndex, i, (this.tableIndex[i] + value * 15))
        }
      }
    },
    // 导出Excel
    sheet() {
      if (localStorage.getItem('IE') === "true") {
        this.$message.warning({
          showClose: true,
          message: "IE浏览器无法导出Excel，请更换浏览器后重试",
        });
        return
      }
      // 图表base64图片
      let image = this.img()

      let chartsValue = this.chartsValue
      let chartsData = this.chartsData

      let USL = this.number(chartsValue.iUSL)
      let SL = this.number(chartsValue.iSL)
      let LSL = this.number(chartsValue.iLSL)
      let UCLx = this.number(chartsValue.iUCLx)
      let CLx = this.number(chartsValue.iCLx)
      let LCLx = this.number(chartsValue.iLCLx)
      let UCLr = this.number(chartsValue.iUCLr)
      let CLr = this.number(chartsValue.iCLr)
      let LCLr = this.number(chartsValue.iLCLr)

      if (chartsValue.specifications == '单边上限') {
        SL = '----'
        LSL = '----'
      } else if (chartsValue.specifications == '单边下限') {
        USL = '----'
        SL = '----'
      }

      var workbook;
      var worksheet;
      workbook = new Excel.Workbook();
      workbook.created = new Date();
      workbook.modified = new Date();
      worksheet = workbook.addWorksheet('sheet1', {
        pageSetup: { paperSize: 9 } // A4
      });
      worksheet.columns = [{ header: 'X X X X 有限公司' }]
      // 单个单元格
      worksheet.getCell('A2').value = '【' + this.title + '】'
      worksheet.getCell('A3').value = '日期區間:' + chartsData.date1 + ' 至 ' + chartsData.date2
      // 之后调整页面设置配置
      let margin = 0.195
      worksheet.pageSetup.margins = {
        left: 0.3, right: margin,
        top: margin, bottom: margin,
        header: margin, footer: margin
      };
      // 视图缩放
      worksheet.pageSetup.scale = 95
      worksheet.pageSetup.orientation = 'landscape'
      worksheet.pageSetup.horizontalCentered = true
      // 所有列数据居中，设置字体
      for (let i = 1; i < 28; i++) {
        // worksheet.getColumn(i).alignment = { vertical: 'middle', horizontal: 'center' };
        worksheet.getColumn(i).font = { name: '新細明體', family: 4, size: 12 }
      }
      // 单独单元格样式
      worksheet.getCell('A1').alignment = { vertical: 'middle', horizontal: 'center' }
      worksheet.getCell('A2').alignment = { vertical: 'middle', horizontal: 'center' }
      worksheet.getCell('A3').alignment = { vertical: 'middle', horizontal: 'center' }
      worksheet.getCell('A1').font = { name: '新細明體', family: 4, size: 15, bold: false };
      worksheet.getCell('A2').font = { name: '新細明體', family: 4, size: 18, bold: true };
      worksheet.getCell('A3').font = { name: '新細明體', family: 4, size: 12, bold: false };

      // 上方X轴数据
      let x = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE']

      // 导出组数
      let groupNumber = this.groupNumber

      // 根据导出组数，改变数据
      let spaceRatio = (groupNumber - 15) / 5
      let row = [
        [], [], [], []
      ]
      // 中间数据

      // 第七行空格数
      let h7Space = parseInt((groupNumber + 1) / 3) - 1
      let h7Data = [
        '工序类型 : ' + chartsData.processType,
        '产品类型 : ' + chartsData.productType,
        '产品 : ' + chartsData.product,
      ]

      for (let i = 0; i < 3; i++) {
        row[3].push(h7Data[i])
        for (let j = 0; j < h7Space; j++) {
          row[3].push('')
        }
      }

      let rowMidData = [
        ['測量單位 : ' + chartsValue.measuUnit,
        '規格類型 : ' + chartsValue.specifications,
        '規格上限 : ' + USL,
        '規格標準 : ' + SL,
        '規格下限 : ' + LSL],
        [(chartsValue.specifications == '双边对称' || chartsValue.specifications == '单边上限'
          ? 'XUCL : ' + UCLx
          : 'XLCL : ' + LCLx),
        (chartsValue.specifications == '双边对称'
          ? 'RUCL : ' + UCLr
          : '抽样方式 : 随机'),
        'Ca : ' + this.number(chartsValue.iCa),
        '樣本/頻率 : ' + chartsValue.sampleTimes + "次/" + chartsValue.sampleUnit,
          '控制類型: 解析用'],
        [(chartsValue.specifications == '双边对称'
          ? 'XBar : ' + CLx
          : 'Max : ' + this.number(chartsValue.maxValue)),
        (chartsValue.specifications == '双边对称'
          ? 'RBar : ' + CLr
          : 'Min : ' + this.number(chartsValue.minValue)),
        'Cp : ' + this.number(chartsValue.iCp),
        'Std.Dev : ' + this.number(chartsValue.iSigmaP),
        'Pp : ' + this.number(chartsValue.iPp)],
        [(chartsValue.specifications == '双边对称'
          ? 'XLCL : ' + LCLx
          : 'Cpk水準 : 1.670'),
        (chartsValue.specifications == '双边对称'
          ? 'RLCL : ' + LCLr
          : 'PPM : ' + this.number(chartsValue.iPPM)),
        'Cpk : ' + this.number(chartsValue.iCpk),
        'Sigma : ' + this.number(chartsValue.iSigmaA),
        'Ppk : ' + this.number(chartsValue.iPpk)],
        ['Max : ' + this.number(chartsValue.maxValue),
        'Min : ' + this.number(chartsValue.minValue),
          'Cpk水準 : 1.670',
        'PPM : ' + this.number(chartsValue.iPPM),
          '抽样方式 : 随机']
      ]

      if (chartsValue.specifications != '双边对称') {
        for (let i in rowMidData[4]) {
          rowMidData[4][i] = ''
        }
      }

      for (let i = 0; i < 5; i++) {
        row.push([])
        for (let j = 0; j < 5; j++) {
          row[4 + i].push(rowMidData[i][j])
          for (let k = 0; k < spaceRatio + 2; k++) {
            row[4 + i].push('')
          }
        }
      }

      worksheet.addRows(row)

      // 样本数据与图片
      let num = Math.ceil(chartsValue.m_arrXChart.length * 1 / groupNumber) // 图片数量

      for (let i = 0; i < num; i++) {
        // 表格前三行
        let tabTop = [], tabMid = [], tabBottom = []
        for (let j = 0; j < groupNumber + 1; j++) {
          if (j === 0) {
            tabTop[j] = '组数'
            tabMid[j] = this.tab_title[0]
            tabBottom[j] = this.tab_title[1]
          } else {
            tabTop[j] = j + i * groupNumber
            tabMid[j] = chartsValue.m_arrXChart[(j + i * groupNumber) - 1] !== undefined && j < groupNumber + 1 ?
              this.tab_title[0] == '均值' ? (chartsValue.m_arrXChart[(j + i * groupNumber) - 1]).toFixed(3) : (chartsValue.m_arrXChart[(j + i * groupNumber) - 1]).toFixed(this.decimal)
              : ''
            tabBottom[j] = chartsValue.m_arrRChart[(j + i * groupNumber) - 1] !== undefined && j < groupNumber + 1 ? chartsValue.m_arrRChart[(j + i * groupNumber) - 1].toFixed(this.decimal) : ''
          }
        }

        // 单边隐藏 tabBotttom
        if (chartsValue.specifications == '双边对称') {
          worksheet.addRows([tabTop, tabMid, tabBottom])
        } else {
          worksheet.addRows([tabTop, tabMid])
        }

        // worksheet.addRows([tabTop, tabMid])
        // 表格样本
        if (this.tab_title[0] !== '单值') {
          for (let k = 0; k < chartsValue.m_arrGrpSample[0].length * 1; k++) {
            let sample = []
            for (let l = 0; l < groupNumber + 1; l++) {
              if (l === 0) {
                sample[l] = '樣本' + (k + 1)
              } else {
                if (chartsValue.m_arrGrpSample[(l - 1) + i * groupNumber] !== undefined) {
                  sample[l] = chartsValue.m_arrGrpSample[(l - 1) + i * groupNumber][k] !== undefined && l < groupNumber + 1 ? chartsValue.m_arrGrpSample[(l - 1) + i * groupNumber][k].toFixed(this.decimal) : ''
                }
              }
            }
            worksheet.addRows([sample])
          }
        }
        // 图片占位t行
        let t = chartsValue.specifications == '双边对称' ? 36 : 18
        let arr = []
        for (let k = 0; k < t; k++) {
          arr.push([])
        }
        worksheet.addRows(arr)

        // 表格高度
        let h
        if (this.tab_title[0] !== '单值') {
          // h = 3 + chartsValue.m_arrGrpSample[0].length * 1
          h = chartsValue.specifications == '双边对称' ? 3 + chartsValue.m_arrGrpSample[0].length * 1 : 2 + chartsValue.m_arrGrpSample[0].length * 1
        } else {
          // h = 3
          h = chartsValue.specifications == '双边对称' ? 3 : 2
        }
        // 表格样式
        for (let m = 0; m < groupNumber + 1; m++) {
          for (let n = 0; n < h; n++) {
            let cell = worksheet.getCell(x[m] + ((n + 13) + (i * h) + (i * t)))
            cell.font = { name: '新細明體', family: 4, size: 11 }
            // A + 距离头部高度13 + 本身表格高度 + 图片区域36行
            cell.border = {
              top: { style: 'thin', color: { argb: 'FF000000' } },
              right: { style: 'thin', color: { argb: 'FF000000' } },
              bottom: { style: 'thin', color: { argb: 'FF000000' } },
              left: { style: 'thin', color: { argb: 'FF000000' } },
            }
          }
        }

        // 图片位置
        let location1, location2, startLocation, endLocation
        startLocation = 'B'
        switch (this.groupNumber) {
          case 15: {
            endLocation = 'O'
            break
          }
          case 20: {
            endLocation = 'T'
            break
          }
          case 25: {
            endLocation = 'Y'
            break
          }
          case 30: {
            endLocation = 'AD'
            break
          }
        }

        // location1 = `B${15 + h + 1 + (i * (h + t))}:O${5 + h + 16 + (i * (h + t))}`
        // location2 = `B${15 + h + 1 + 6 + (i * (h + t))}:O${5 + h + 6 + 16 + (i * (h + t))}`
        location1 = `${startLocation}${13 + h + 1 + (i * (h + t))}:${endLocation}${13 + h + 15 + 1 + (i * (h + t))}`
        location2 = `${startLocation}${13 + h + 1 + 17 + (i * (h + t))}:${endLocation}${13 + h + 17 + 15 + 1 + (i * (h + t))}`
        // 距离图片高度13 + 表格高度h + 图片间隔1 + (i * ( 表格高度h + 图片占位36(t) ))

        // 图表图片
        let imageId1 = workbook.addImage({
          base64: image.base64_1[i],
          extension: 'jpeg'
        });
        worksheet.addImage(imageId1, location1);

        if (chartsValue.specifications == '双边对称') {
          let imageId2 = workbook.addImage({
            base64: image.base64_2[i],
            extension: 'jpeg'
          });
          worksheet.addImage(imageId2, location2);
        }
      }

      let ratio = 1.39 // 缩放倍率
      // 列宽
      worksheet.getColumn(1).width = (6.5 / 1.66) * ratio
      for (let i = 0; i < 31; i++) {
        worksheet.getColumn(i + 2).width = (6.5 / 1.66) * ratio
      }

      // 行高
      worksheet.getRow(1).height = 20.25 * ratio
      worksheet.getRow(2).height = 25.5 * ratio
      worksheet.getRow(3).height = 16.5 * ratio
      worksheet.getRow(4).height = 4.5 * ratio
      worksheet.getRow(5).height = 4.5 * ratio
      worksheet.getRow(6).height = 4.5 * ratio

      if (chartsValue.specifications != '双边对称') {
        worksheet.getRow(12).height = 4.5 * ratio
      }

      // 合并单元格
      worksheet.mergeCells('A1:' + x[groupNumber] + '1');
      worksheet.mergeCells('A2:' + x[groupNumber] + '2');
      worksheet.mergeCells('A3:' + x[groupNumber] + '3');

      // 第七行每格合并个数
      let h7 = parseInt((groupNumber + 1) / 3)

      for (let i = 0; i < 3; i++) {
        worksheet.mergeCells(`${x[h7 * i]}7:${x[(h7 * (i + 1)) - 1]}7`);
      }

      for (let i = 0; i < 5; i++) {
        for (let j = 0; j < 5; j++) {
          worksheet.mergeCells(`${x[(3 + spaceRatio) * j]}${8 + i}:${x[((3 + spaceRatio) * (j + 1)) - 1]}${8 + i}`);
        }
      }

      let t = this.title
      workbook.xlsx.writeBuffer().then(function (buffer) {
        saveAs.saveAs(new Blob([buffer], {
          type: 'application/octet-stream'
        }), t + '.' + 'xls');
      });
    },
    // 获取所有图表base64图片
    img() {
      let chartsData = this.chartsData
      let chartsValue = this.chartsValue
      let base64_1 = []
      let base64_2 = []
      let groupNumber = this.groupNumber
      let num = Math.ceil(chartsValue.m_arrXChart.length * 1 / groupNumber) // 图片数量
      // 图1、图2数据存放
      let arr1 = []
      let arr2 = []
      // 横轴数据
      let horizontalAxis = JSON.parse(JSON.stringify(this.xData))
      for (let i of chartsValue.m_arrXChart) {
        arr1.push(i)
      }
      for (let i in chartsValue.m_arrRChart) {
        if (chartsData.cmbSpecChartType === 'X-RM') {
          if (i == 0) {
            arr2.push('')
          } else {
            arr2.push(chartsValue.m_arrRChart[i])
          }
        } else {
          arr2.push(chartsValue.m_arrRChart[i])
        }
      }

      // 补齐最后一张图片空数据
      for (let i = 0; i < num * groupNumber; i++) {
        if (arr1[i] == undefined) {
          arr1[i] = ''
          arr2[i] = ''
          horizontalAxis[i] = ''
        }
      }

      for (let i = 0; i < num; i++) {
        let myChart1 = this.echarts.init(document.getElementById('temporary_img1'));
        let option1 = myChart1.getOption()
        // console.log(option1)
        option1.series[0].data = arr1.slice(i * groupNumber, groupNumber + i * groupNumber)
        option1.xAxis[0].data = horizontalAxis.slice(i * groupNumber, groupNumber + i * groupNumber)
        option1.dataZoom = []
        option1.toolbox = {}
        // 重新设置y轴最大最小值
        let spacing = (chartsValue.iUCLx - chartsValue.iCLx) / 4
        if (spacing == 0) {
          spacing = chartsValue.iUSL - chartsValue.iSL
        }
        let max
        let min
        max = (chartsValue.iUCLx + spacing).toFixed(3) * 1
        min = (chartsValue.iLCLx - spacing).toFixed(3) * 1
        if (chartsValue.specifications == '单边下限') {
          max = (chartsValue.maxValue + (chartsValue.iLSL / 10)).toFixed(3) * 1
          min = (chartsValue.iLSL - (chartsValue.iLSL / 10)).toFixed(3) * 1
        }
        option1.yAxis[0].max = max
        option1.yAxis[0].min = min
        // 线条样式
        option1.series[0].lineStyle.width = 2
        option1.series[0].symbolSize = 8
        option1.series[0].markLine.data[3].label.formatter = 'UCL'
        option1.series[0].markLine.data[4].label.formatter = 'CL'
        option1.series[0].markLine.data[5].label.formatter = 'LCL'
        option1.series[0].markLine.data[1].yAxis = 999
        option1.series[0].markLine.data[4].lineStyle.color = '#090'
        option1.series[0].markLine.data[4].lineStyle.type = 'solid'
        // option1.series[0].markLine.data[4].lineStyle.width = 2
        // option1.series[0].markLine.data[3].lineStyle.width = 2
        // option1.series[0].markLine.data[5].lineStyle.width = 2
        // 根据选择导出组数，计算图表宽度（总宽度-12%）
        option1.grid[0].width = (60 * this.groupNumber) - (60 * this.groupNumber * 0.12) + 'px'

        // canvas宽度修改
        myChart1.resize();
        myChart1.setOption(option1, true)

        base64_1.push(myChart1.getDataURL({
          backgroundColor: '#fff'
        }))

        let myChart2 = this.echarts.init(document.getElementById('temporary_img2'));
        let option2 = myChart2.getOption()
        option2.series[0].data = arr2.slice(i * groupNumber, groupNumber + i * groupNumber)
        option2.xAxis[0].data = horizontalAxis.slice(i * groupNumber, groupNumber + i * groupNumber)
        option2.dataZoom = []
        option2.toolbox = {}
        // 线条样式
        option2.series[0].lineStyle.width = 2
        option2.series[0].symbolSize = 8
        option2.series[0].markLine.data[3].label.formatter = 'UCL'
        option2.series[0].markLine.data[4].label.formatter = 'CL'
        option2.series[0].markLine.data[5].label.formatter = 'LCL'
        option2.series[0].markLine.data[4].lineStyle.color = '#090'
        option2.series[0].markLine.data[4].lineStyle.type = 'solid'
        // option2.series[0].markLine.data[4].lineStyle.width = 2
        // option2.series[0].markLine.data[3].lineStyle.width = 2
        // option2.series[0].markLine.data[5].lineStyle.width = 2
        option2.grid[0].width = (60 * this.groupNumber) - (60 * this.groupNumber * 0.12) + 'px'

        myChart2.resize();
        myChart2.setOption(option2, true)

        base64_2.push(myChart2.getDataURL({
          backgroundColor: '#fff'
        }))
      }
      return { base64_1, base64_2 }
    },
    // 修改 X、R图、样本值 数据 （图表、图表数据索引、具体样本数据索引）
    change(chartIndex, index, index2) {
      let chartsData = this.chartsData
      let chartsValue = this.chartsValue
      // 判断是否可以修改图表
      if (!this.storage.get('change')) {
        return
      }
      // 判断是否有此索引
      if (chartsValue.m_arrXChart[index] == undefined) {
        return
      }
      // R 图移动值首个数据不可修改
      if (chartIndex == 1 && this.tab_title[1] == '移动值' && index == 0) {
        return
      }
      // 高亮选中列数
      this.activationId = index
      // 同步表格页数
      this.tableIndex = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
      let page = parseInt(index / 15)
      for (let i in this.tableIndex) {
        Vue.set(this.tableIndex, i, (this.tableIndex[i] + page * 15))
      }
      // console.log(parseInt(index / 15))
      if (chartIndex == 0) {
        this.input = chartsValue.m_arrXChart[index]
      } else if (chartIndex == 1) {
        this.input = chartsValue.m_arrRChart[index]
      } else {
        this.input = chartsValue.m_arrGrpSample[index][index2]
      }
      // 若为修改 标准差，则给sample添加值，进行显示
      if (chartsData.chartType === '均值-标准差图') {
        this.sample = []
        for (let i = 0; i < chartsValue.m_arrGrpSample[this.index].length; i++) {
          this.sample.push({ value: chartsValue.m_arrGrpSample[this.index][i] })
        }
      }
      this.index = index
      this.index2 = index2
      this.placeholder = this.input
      this.input_title = this.tab_title[chartIndex] ? this.tab_title[chartIndex] : "样本值"
      this.dialogVisible = true
    },
    // 确认修改
    update() {
      this.dialogVisible = false

      let chartsData = this.chartsData
      let chartsValue = this.chartsValue

      this.loading = true
      // 非空认证
      if (this.input === '') {
        this.$message.error({
          showClose: true,
          message: "请输入修改后数值",
        });
        this.loading = false
        return
      }
      // 正则验证 数字
      let reg = new RegExp(/^-?\d*\.?\d+$/)
      if (!reg.test(this.input)) {
        this.$message.error({
          showClose: true,
          message: "请输入正确数字",
        });
        this.loading = false
        return
      }
      // 判断修改的是 X 、R 或 样本 的数据
      if (this.input_title === this.tab_title[0]) {
        // X
        // console.log("X图 数据修改")
        switch (chartsData.chartType) {
          case '单值-移动极差图': {
            chartsValue.m_arrGrpSample[this.index][0] = this.input * 1
            break;
          }
          case '均值-标准差图': {
            // 将每组的所有样本值更改为 input 的值，然后每组每个样本加上总和为 input/10 的随机数，然后再减去总和为 input/10 的随机数
            let random1 = [], random2 = []
            let length = chartsValue.m_arrGrpSample[this.index].length
            random1 = this.randGenerator(length, (this.input * 1 / 10))
            random2 = this.randGenerator(length, (this.input * 1 / 10))
            for (let i in chartsValue.m_arrGrpSample[this.index]) {
              if (chartsValue.m_arrGrpSample[this.index][i] !== 0) {
                chartsValue.m_arrGrpSample[this.index][i] = (this.input * 1 + random1[i] - random2[i]).toFixed(4) * 1
              }
            }
            break;
          }
          case '均值-极差图': {
            // 将每组的所有样本值更改为 input 的值，然后每组每个样本加上总和为 input/10 的随机数，然后再减去总和为 input/10 的随机数
            let random1 = [], random2 = []
            let length = chartsValue.m_arrGrpSample[this.index].length
            random1 = this.randGenerator(length, (this.input * 1 / 10))
            random2 = this.randGenerator(length, (this.input * 1 / 10))
            for (let i in chartsValue.m_arrGrpSample[this.index]) {
              if (chartsValue.m_arrGrpSample[this.index][i] !== 0) {
                chartsValue.m_arrGrpSample[this.index][i] = (this.input * 1 + random1[i] - random2[i]).toFixed(4) * 1
              }
            }
            break;
          }
          case '中位数-极差图': {
            let length = chartsValue.m_arrGrpSample[0].length
            if (length % 2 == 0) {
              // 双数
              let x1, x2
              // (中位数 * 2 - ( x1 + x2 ))/2
              let y = 0
              x1 = chartsValue.m_arrGrpSample[this.index][(length / 2) - 1]
              x2 = chartsValue.m_arrGrpSample[this.index][(length / 2)]
              y = (this.input * 2 - (x1 + x2)) / 2
              chartsValue.m_arrGrpSample[this.index][(length / 2) - 1] += y
              chartsValue.m_arrGrpSample[this.index][(length / 2)] += y
            } else {
              //单数
              chartsValue.m_arrGrpSample[this.index][parseInt(length / 2)] = this.input * 1
            }
            break;
          }
        }
      } else if (this.input_title === this.tab_title[1]) {
        // R
        // console.log("R图 数据修改")
        switch (chartsData.chartType) {
          case '单值-移动极差图': {
            chartsValue.m_arrGrpSample[this.index][0] = (chartsValue.m_arrGrpSample[this.index - 1][0] + this.input * 1).toFixed(3) * 1
            break;
          }
          case '均值-标准差图': {
            for (let i in this.sample) {
              if (!reg.test(this.sample[i]['value'])) {
                this.$message.error({
                  showClose: true,
                  message: "请输入正确数字",
                });
                this.loading = false
                return
              }
              chartsValue.m_arrGrpSample[this.index][i] = this.sample[i]['value'] * 1
            }
            break;
          }
          case '均值-极差图': {
            let samples = [] // 样本数据
            let min, max // 最小值、最大值

            for (let i in chartsValue.m_arrGrpSample[this.index]) {
              if (chartsValue.m_arrGrpSample[this.index][i] !== 0) {
                samples.push({ value: chartsValue.m_arrGrpSample[this.index][i], index: i })
              }
            }
            min = samples.reduce((num1, num2) => {
              return num1.value < num2.value ? num1 : num2
            })
            max = samples.reduce((num1, num2) => {
              return num1.value > num2.value ? num1 : num2
            })

            let poor = 0 // 修改前和修改后值的 差
            if (chartsValue.m_arrRChart[this.index] > this.input * 1) {
              poor = chartsValue.m_arrRChart[this.index] - this.input * 1
              chartsValue.m_arrGrpSample[this.index][min.index] += poor
              for (let i in chartsValue.m_arrGrpSample[this.index]) {
                if (chartsValue.m_arrGrpSample[this.index][i] * 1 < chartsValue.m_arrGrpSample[this.index][min.index] * 1) {
                  if (chartsValue.m_arrGrpSample[this.index][i] * 1 !== 0) {
                    chartsValue.m_arrGrpSample[this.index][i] = chartsValue.m_arrGrpSample[this.index][min.index]
                  }
                }
              }
            } else {
              poor = this.input * 1 - chartsValue.m_arrRChart[this.index]
              chartsValue.m_arrGrpSample[this.index][max.index] += poor
            }
            break;
          }
          case '中位数-极差图': {
            let samples = [] // 样本数据
            let min, max // 最小值、最大值

            for (let i in chartsValue.m_arrGrpSample[this.index]) {
              if (chartsValue.m_arrGrpSample[this.index][i] !== 0) {
                samples.push({ value: chartsValue.m_arrGrpSample[this.index][i], index: i })
              }
            }
            min = samples.reduce((num1, num2) => {
              return num1.value < num2.value ? num1 : num2
            })
            max = samples.reduce((num1, num2) => {
              return num1.value > num2.value ? num1 : num2
            })

            let poor = 0 // 修改前和修改后值的 差
            if (chartsValue.m_arrRChart[this.index] > this.input * 1) {
              poor = chartsValue.m_arrRChart[this.index] - this.input * 1
              chartsValue.m_arrGrpSample[this.index][min.index] += poor
              for (let i in chartsValue.m_arrGrpSample[this.index]) {
                if (chartsValue.m_arrGrpSample[this.index][i] * 1 < chartsValue.m_arrGrpSample[this.index][min.index] * 1) {
                  if (chartsValue.m_arrGrpSample[this.index][i] * 1 !== 0) {
                    chartsValue.m_arrGrpSample[this.index][i] = chartsValue.m_arrGrpSample[this.index][min.index]
                  }
                }
              }
            } else {
              poor = this.input * 1 - chartsValue.m_arrRChart[this.index]
              chartsValue.m_arrGrpSample[this.index][max.index] += poor
            }
            break;
          }
        }
      } else {
        // 样本
        // console.log("样本 数据修改")
        chartsValue.m_arrGrpSample[this.index][this.index2] = this.input * 1
      }
      this.calculate()
      midData(chartsData, chartsValue)
      this.MaxMin()
      this.specifications()
      this.originalData()
      // console.log(chartsValue)
      this.modifyChartData('main1', chartsValue.m_arrXChart)
      this.modifyChartData('main2', chartsValue.m_arrRChart)
      this.modifyChartData('temporary_img1', chartsValue.m_arrXChart)
      this.modifyChartData('temporary_img2', chartsValue.m_arrRChart)
      let arrGrpSample = []
      for (let i = 0; i < this.sampleValue.length; i++) {
        arrGrpSample.push(this.sampleValue[i])
      }
      // 请求修改接口
      // let params = {
      //   productNo: chartsData.productInformation.productNo,
      //   statTime: chartsData.date1,
      //   endTime: chartsData.date2,
      //   arrGrpSample
      // }
      // changeChartValue(params).then(res => {
      //   console.log(res.data)
      //   this.$message.success({
      //     showClose: true,
      //     message: "修改成功",
      //   });
      //   this.loading = false
      //   this.dialogVisible = false
      // }).catch(err => {
      //   this.$message.error({
      //     showClose: true,
      //     message: "服务器出错，请联系管理员",
      //   });
      //   this.loading = false
      //   this.dialogVisible = false
      // })
      this.$message.success({
        showClose: true,
        message: "修改成功",
      });
      this.loading = false
      this.dialogVisible = false
    },
    // 计算两个图表数据
    calculate() {
      let chartsData = this.chartsData
      let chartsValue = this.chartsValue
      chartsValue.m_arrXChart = []
      chartsValue.m_arrRChart = []
      switch (chartsData.chartType) {
        case '单值-移动极差图': {
          // 全部样本
          let sample = []
          for (let i of chartsValue.m_arrGrpSample) {
            for (let j of i) {
              sample.push(j)
            }
          }
          // 单值
          chartsValue.m_arrXChart = sample
          chartsValue.m_arrGrpSample = []
          for (let i in sample) {
            // 重排样本
            chartsValue.m_arrGrpSample.push([sample[i]])
            // 移动极差
            if (i == 0) {
              chartsValue.m_arrRChart[i] = 0
            } else {
              chartsValue.m_arrRChart[i] = Math.abs(chartsValue.m_arrXChart[i - 1] - chartsValue.m_arrXChart[i]).toFixed(3) * 1
            }
          }
          break;
        }
        case '均值-标准差图': {
          for (let i of chartsValue.m_arrGrpSample) {
            let sum = 0
            let x, r
            for (let j of i) {
              sum += j
            }
            // 均值
            x = (sum / chartsValue.m_arrGrpSample[0].length).toFixed(4) * 1
            chartsValue.m_arrXChart.push(x)
            // 标准差
            r = this.stddev(i, chartsValue.m_arrGrpSample[0].length).toFixed(3) * 1
            chartsValue.m_arrRChart.push(r)
          }
          break;
        }
        case '均值-极差图': {
          for (let i of chartsValue.m_arrGrpSample) {
            let sum = 0
            let x, r
            for (let j of i) {
              sum += j
            }
            // 均值
            x = (sum / chartsValue.m_arrGrpSample[0].length).toFixed(4) * 1
            chartsValue.m_arrXChart.push(x)
            // 极差
            let min = i.reduce((num1, num2) => {
              return num1 < num2 ? num1 : num2
            })
            let max = i.reduce((num1, num2) => {
              return num1 > num2 ? num1 : num2
            })
            r = (max - min).toFixed(3) * 1
            chartsValue.m_arrRChart.push(r)
          }
          break;
        }
        case '中位数-极差图': {
          for (let i of chartsValue.m_arrGrpSample) {
            let x, r
            let length = chartsValue.m_arrGrpSample[0].length
            if (length % 2 == 0) {
              // 双数
              let x1, x2
              x1 = i[(length / 2) - 1]
              x2 = i[length / 2]
              x = (x1 + x2) / 2
            } else {
              //单数
              x = i[parseInt(length / 2)]
            }
            chartsValue.m_arrXChart.push(x.toFixed(3) * 1)
            // 极差
            let min = i.reduce((num1, num2) => {
              return num1 < num2 ? num1 : num2
            })
            let max = i.reduce((num1, num2) => {
              return num1 > num2 ? num1 : num2
            })
            r = (max - min).toFixed(3) * 1
            chartsValue.m_arrRChart.push(r)
          }
          break;
        }
      }
    },
    // 判断规格,计算数据
    specifications() {
      let chartsValue = this.chartsValue
      let Ca, Cp, Cpk, Pp, Ppk
      let CLx = chartsValue.iCLx // 群体均值
      let CLr = chartsValue.iCLr // 极差均值
      let USL = chartsValue.iUSL // 规格上限
      let LSL = chartsValue.iLSL // 规格下限
      let d2 = chartsValue.d_2 // d2查看值
      let stddev = chartsValue.iSigmaP // 标准差
      if (chartsValue.iSL == 0 && (USL == 0 || LSL == 0)) {
        // console.log('单边')

        // 单边规格
        Ca = '----'
        let value // 上限或下限
        if (chartsValue.iUSL == 0) {
          // 只有下限
          chartsValue.specifications = '单边下限'
          value = chartsValue.iLSL
          Ppk = (CLx - LSL) / (3 * stddev)
        } else {
          // 只有上限
          chartsValue.specifications = '单边上限'
          value = chartsValue.iUSL
          Ppk = (USL - CLx) / (3 * stddev)
        }
        Cp = Math.abs(value - CLx) / (3 * (CLr / d2))
        Cpk = Math.abs(value - CLx) / (3 * (CLr / d2))
        Pp = Math.abs(value - CLx) / (3 * stddev)
      } else {
        // console.log('双边')
        chartsValue.specifications = '双边对称'
        // 双边规格
        Ca = (CLx - ((USL + LSL) / 2)) / ((USL - LSL) / 2)
        Cp = (USL - LSL) / (6 * (CLr / d2))
        Cpk = (1 - Math.abs(Ca)) * Cp
        Pp = (USL - LSL) / (6 * stddev)
        Ppk = (1 - Math.abs(Ca)) * Pp
      }
      chartsValue.iCa = Ca
      chartsValue.iCp = Cp
      chartsValue.iCpk = Cpk
      chartsValue.iPp = Pp
      chartsValue.iPpk = Ppk
      if (chartsValue.iPPM == undefined) {
        chartsValue.iPPM = '----'
      }
    },
    // 同步原始数据
    originalData() {
      let chartsValue = this.chartsValue
      let sampleValue = this.sampleValue
      let samples = []
      for (let i of chartsValue.m_arrGrpSample) {
        for (let j of i) {
          samples.push(j)
        }
      }
      for (let i = 0; i < sampleValue.length; i++) {
        sampleValue[i].mfg = samples[i].toString()
        sampleValue[i].groupdiff = sampleValue[i].groupdiff.toString()
        sampleValue[i].sampleTimes = sampleValue[i].sampleTimes.toString()
      }
      // console.log(sampleValue)
    },
    // 修改图表数据
    modifyChartData(id, data) {
      let chartsValue = this.chartsValue
      let myChart = this.echarts.init(document.getElementById(id));
      let option = myChart.getOption()
      // console.log(option)
      // 图表数据
      option.series[0].data = data
      option.xAxis[0].data = this.xData
      // 图表最大、最小值
      let max, min
      if (id == 'main1' || id == 'temporary_img1') {
        max = (chartsValue.iUSL + (chartsValue.iUSL - chartsValue.iLSL) / 10).toFixed(3) * 1
        min = (chartsValue.iLSL - (chartsValue.iUSL - chartsValue.iLSL) / 10).toFixed(3) * 1
      } else {
        max = (chartsValue.iUCLr + (chartsValue.iUCLr - chartsValue.iLCLr) / 5).toFixed(3) * 1
        min = (chartsValue.iLCLr - (chartsValue.iUCLr - chartsValue.iLCLr) / 10).toFixed(3) * 1
      }
      if (chartsValue.specifications == '单边下限') {
        max = (chartsValue.maxValue + (chartsValue.iLSL / 10)).toFixed(3) * 1
        min = (chartsValue.iLSL - (chartsValue.iLSL / 10)).toFixed(3) * 1
      }
      option.yAxis[0].max = max
      option.yAxis[0].min = min
      // 上下限值
      let markLine = [chartsValue.iUSL, chartsValue.iSL, chartsValue.iLSL]
      if (id == 'main1' || id == 'temporary_img1') {
        markLine.push(chartsValue.iUCLx)
        markLine.push(chartsValue.iCLx)
        markLine.push(chartsValue.iLCLx)
      } else {
        markLine[0] = 999
        markLine[1] = 999
        markLine[2] = 999
        markLine.push(chartsValue.iUCLr)
        markLine.push(chartsValue.iCLr)
        markLine.push(chartsValue.iLCLr)
      }
      if (chartsValue.specifications == '单边上限') {
        markLine[1] = 999
        markLine[2] = 999
        markLine[4] = 999
        markLine[5] = 999
      } else if (chartsValue.specifications == '单边下限') {
        markLine[0] = 999
        markLine[1] = 999
        markLine[3] = 999
        markLine[4] = 999
      }
      for (let i in markLine) {
        option.series[0].markLine.data[i].yAxis = markLine[i]
      }
      myChart.setOption(option, true)
    },
    // 图表 (div的id)
    chart(id) {
      let chartsValue = this.chartsValue
      // 图表数据
      let data
      if (id == "main1" || id == "temporary_img1") {
        data = {
          data: chartsValue.m_arrXChart,
          markLine: {
            USL: chartsValue.iUSL,
            SL: chartsValue.iSL,
            LSL: chartsValue.iLSL,
            UCL: chartsValue.iUCLx,
            CL: chartsValue.iCLx,
            LCL: chartsValue.iLCLx,
            length: 6
          },
          // legend: '内层油墨厚度-t01-内层油墨厚度-过程检验单值',
          legend: this.tab_title[0]
        }
      } else {
        data = {
          data: chartsValue.m_arrRChart,
          markLine: {
            UCL: chartsValue.iUCLr,
            CL: chartsValue.iCLr,
            LCL: chartsValue.iLCLr,
            length: 3
          },
          // legend: '内层油墨厚度-t01-内层油墨厚度-过程检验极差',
          legend: this.tab_title[1]
        }
      }
      if (chartsValue.specifications == '单边上限') {
        data.markLine.SL = 999
        data.markLine.LSL = 999
        data.markLine.CL = 999
        data.markLine.LCL = 999
      } else if (chartsValue.specifications == '单边下限') {
        data.markLine.USL = 999
        data.markLine.SL = 999
        data.markLine.UCL = 999
        data.markLine.CL = 999
      }
      var myChart = this.echarts.init(document.getElementById(id));
      let xData = this.xData
      let change = this.change
      // 图例说明
      let legend = data.legend
      // 图表最大、最小值
      let max, min
      if (id == 'main1' || id == "temporary_img1") {
        max = (chartsValue.iUSL + (chartsValue.iUSL - chartsValue.iLSL) / 10).toFixed(3) * 1
        min = (chartsValue.iLSL - (chartsValue.iUSL - chartsValue.iLSL) / 10).toFixed(3) * 1
      } else {
        max = (chartsValue.iUCLr + (chartsValue.iUCLr - chartsValue.iLCLr) / 5).toFixed(3) * 1
        min = (chartsValue.iLCLr - (chartsValue.iUCLr - chartsValue.iLCLr) / 10).toFixed(3) * 1
      }
      if (chartsValue.specifications == '单边下限') {
        max = (chartsValue.maxValue + (chartsValue.iLSL / 10)).toFixed(3) * 1
        min = (chartsValue.iLSL - (chartsValue.iLSL / 10)).toFixed(3) * 1
      }
      // console.log(max.toFixed(3) * 1, min.toFixed(3) * 1)
      // 根据图表数据个数，设置底部滚动条属性
      let dataZoom = [{
        end: 100,
        filterMode: "filter",
        start: 0,
        type: "slider",
        xAxisIndex: [0],
        yAxisIndex: [],
      }]
      let x = data.data.length
      switch (true) {
        case (x <= 20): {
          dataZoom = null
          break;
        }
        case (x > 20 && x <= 30): {
          dataZoom[0].end = 50
          break;
        }
        case (x > 30 && x <= 50): {
          dataZoom[0].end = 33
          break;
        }
        case (x > 50 && x <= 60): {
          dataZoom[0].end = 25
          break;
        }
        case (x > 60 && x <= 90): {
          dataZoom[0].end = 20
          break;
        }
        case (x > 90): {
          dataZoom[0].end = 14
          break;
        }
      }

      myChart.setOption({
        animation: (id == "main1" || id == "main2") ? true : false,
        legend: {
          data: [legend]
        },
        tooltip: {
          position: ["10", "10"],
          show: true,
          trigger: "axis"
        },
        toolbox: {
          orient: "horizontal",
          show: true,
          feature: {
            restore: { //重置
              show: true
            },
            magicType: { //动态类型切换
              type: ['line', 'bar']
            },
            // saveAsImage: { //保存图片
            //   show: true,
            //   type: "png"
            // },
          }
        },
        xAxis: {
          data: xData,
          gridIndex: 0,
          nameLocation: "end",
          position: "bottom",
          scale: true,
          show: true,
          splitLine: {
            show: true,
            lineStyle: {
              type: 'dashed',

              // type: 'solid'
            },
          },
          axisLabel: {
            show: true,
            textStyle: {
              // fontSize: 16
            }
          },
          type: "category"
        },
        yAxis: {
          gridIndex: 0,
          min: min,
          max: max,
          nameLocation: "end",
          position: "left",
          scale: true,
          show: true,
          splitLine: {
            show: true,
            lineStyle: {
              type: 'dashed'
              // type: 'solid'
            },
          },
          axisLabel: {
            show: true,
            textStyle: {
              // fontSize: 16
            }
          },
          type: "value"
        },
        series: [{
          name: legend,
          showAllSymbol: true,
          showSymbol: true,
          smooth: false,
          symbol: "circle",
          symbolSize: 4,
          type: "line",
          xAxisIndex: 0,
          yAxisIndex: 0,
          data: data.data,
          itemStyle: {
            normal: {
              color: "blue",
              lineStyle: {
                color: "blue",
                width: 1
              },
              label: {
                show: false
              }
            }
          },
          markLine: {
            symbol: ['none', 'none'],
            precision: 3,
            data: [{
              name: "USL",
              // 若为第二个图，则不显示绿色线条
              yAxis: data.markLine.length == 6 ? data.markLine.USL : 999,
              lineStyle: {
                normal: {
                  color: "#090",
                  type: "solid",
                  width: 1
                }
              }
            }, {
              name: "SL",
              yAxis: data.markLine.length == 6 ? data.markLine.SL : 999,
              lineStyle: {
                normal: {
                  color: "#090",
                  type: "solid",
                  width: 1
                }
              }
            }, {
              name: "LSL",
              yAxis: data.markLine.length == 6 ? data.markLine.LSL : 999,
              lineStyle: {
                normal: {
                  color: "#090",
                  type: "solid",
                  width: 1
                }
              }
            }, {
              name: "UCL",
              yAxis: data.markLine.UCL,
              lineStyle: {
                normal: {
                  color: "#D53A35",
                  type: "dashed",
                  width: 1
                }
              }
            }, {
              name: "CL",
              yAxis: data.markLine.CL,
              lineStyle: {
                normal: {
                  color: "#D53A35",
                  type: "dashed",
                  width: 1
                }
              }
            }, {
              name: "LCL",
              yAxis: data.markLine.LCL,
              lineStyle: {
                normal: {
                  color: "#D53A35",
                  type: "dashed",
                  width: 1
                }
              }
            },]
          }
        }],
        grid: {
          left: "4%",
          right: "8%",
          bottom: "10%",
          containLabel: true
        },
        dataZoom
      })

      myChart.on('click', function (params) {
        // console.log(params.dataIndex)
        if (params.componentType === 'series') {
          let chartIndex = (id == 'main1') ? 0 : 1
          change(chartIndex, params.dataIndex)
        }
      })
    },
    // 最大、最小值
    MaxMin() {
      let chartsValue = this.chartsValue
      let samples = []
      let min, max // 最小值、最大值
      for (let i of chartsValue.m_arrGrpSample) {
        for (let j of i) {
          samples.push(j)
        }
      }
      min = samples.reduce((num1, num2) => {
        return num1 < num2 ? num1 : num2
      })
      max = samples.reduce((num1, num2) => {
        return num1 > num2 ? num1 : num2
      })
      chartsValue.minValue = min
      chartsValue.maxValue = max
    },
    // 生成一组随机数，固定总和
    randGenerator(n, sum) {
      let aryRet = [];
      let fSumTmp = sum;
      let iAcc = 0;
      for (let i = 0; i < (n - 1); i++) {
        let iTmp = (Math.random() * (fSumTmp / 2)).toFixed(3) * 1
        aryRet.push(iTmp);
        fSumTmp -= iTmp;
        iAcc += iTmp;
      }
      aryRet.push(sum - iAcc);
      return aryRet;
    },
    // 求和
    sum(x, y) {
      return x + y
    },
    // 平方
    square(x) {
      return x * x
    },
    // 标准差
    stddev(data, length) {
      let sum = 0
      let length2 = 0
      for (let i in data) {
        if (data[i] !== 0) {
          sum += data[i]
          length2++
        }
      }
      let mean = data.reduce(this.sum) / (length2) // 平均数
      let deviations = data.map(function (x) { return x - mean })
      let stddev = Math.sqrt(deviations.map(this.square).reduce(this.sum) / (length - 1))
      return stddev
    }
  },
}
</script>

<style scoped lang='scss'>
.Chart {
  width: 1000px;
  min-width: 1000px;
  max-width: 1000px;
  min-height: 100vh;
  margin-top: 20px;
  margin-bottom: 60px;
  background-color: #fff;
  box-shadow: 1px 3px 3px #ccc;
  border-radius: 8px;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  .panel-group {
    width: 100%;
    margin-bottom: 50px;
    .page {
      margin: 20px 0 10px 5%;
    }
    .table-top {
      border: 1px solid #bbb;
      border-bottom: 0px solid #bbb;
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      width: 90%;
      margin-left: 5%;
      margin-top: 20px;
      div {
        width: 20%;
        height: 34px;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .head {
        margin-left: 25%;
        width: 50%;
      }
      .type {
        width: 33%;
      }
    }
    .table {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      width: 90%;
      margin-left: 5%;
      border-right: 1px #bbb solid;
      border-bottom: 1px #bbb solid;
      .column {
        line-height: 1.9em;
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        .row {
          width: 100%;
          border-top: 1px #bbb solid;
          border-left: 1px #bbb solid;
          height: 1.9em;
          text-align: center;
          transition: all 0.5s;
        }
      }
    }
    .title {
      width: 100%;
      background-color: #e0ecff;
      background: linear-gradient(to bottom, #eff5ff 0, #e0ecff 100%);
      color: #31708f;
      border-color: #bce8f1;
      padding: 10px 15px;
      border-top-left-radius: 3px;
      border-top-right-radius: 3px;
    }
  }
  .chart {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .dialog {
    display: flex;
    flex-direction: row;
    align-items: center;
    margin-left: 20px;
    min-height: 50px;
  }
  .temporary {
    max-width: 2000px;
    margin-top: 0px;
    max-height: 1px;
    overflow: hidden;
  }
}
</style>